package com.jw.blog.wblog.controller;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jw.blog.annotation.AccessLimit;
import com.jw.blog.annotation.SystemLog;
import com.jw.blog.utils.BlogIdSafeUtil;
import com.jw.blog.utils.ConstantUtil;
import com.jw.blog.wblog.entity.Blog;
import com.jw.blog.wblog.entity.BlogType;
import com.jw.blog.wblog.entity.custom.ResultBean;
import com.jw.blog.wblog.service.IBlogService;
import com.jw.blog.wblog.service.IBlogTypeService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 无良芳
 * @since 2020-06-17
 */
@RestController
public class BlogController {

    @Resource
    private IBlogService iBlogService;

    @Resource
    private IBlogTypeService iBlogTypeService;


    @SystemLog(description = ConstantUtil.BLOG_SELECT, userType = ConstantUtil.USERTYPE_USER)
    @GetMapping(value = "/find/{id}.html")
    public ModelAndView selectBlogById(@PathVariable Integer id) {
        ModelAndView view = new ModelAndView();
        if (id == null || id <= 0) {
            view.setViewName("error/404");
        } else {
            Blog blog = iBlogService.getById(BlogIdSafeUtil.blogIdToSafe(id));
            if (ObjectUtil.isNull(blog)) {
                //查询的博客不存在
                view.setViewName("error/404");
            } else {
                //点击量的增加
                blog.setClickNum(blog.getClickNum()+1);
                iBlogService.updateById(blog);

                view.addObject("blog", blog);
                view.setViewName("page/info");
            }

        }
        return view;
    }

    /**
     * 查询下一篇博客信息
     *
     * @param id 传入下一篇博客的id
     * @return 博客全部信息
     */
    @GetMapping(value = "/selectNextBlog")
    public ResultBean<Blog> selectNextBlog(@RequestParam(value = "id") Integer id) {
        QueryWrapper<Blog> blogQueryWrapper = new QueryWrapper<>();
        blogQueryWrapper.lambda()
                .gt(Blog::getId, id)
                .eq(Blog::getStatus, 1)
                .orderByAsc(Blog::getId)
                .last("limit 1");
        Blog blog = iBlogService.getOne(blogQueryWrapper);
        ResultBean<Blog> resultBean = new ResultBean<>();
        if (ObjectUtil.isNotNull(blog)) {
            resultBean.setData(blog);
        } else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    /**
     * 查询上一篇博客
     *
     * @param id 传入id
     * @return 博客全部信息
     */
    @RequestMapping(value = "/selectPrevBlog")
    public ResultBean<Blog> selectPrevBlog(@RequestParam(value = "id") Integer id) {
        QueryWrapper<Blog> blogQueryWrapper = new QueryWrapper<>();
        blogQueryWrapper.lambda()
                .lt(Blog::getId, id)
                .eq(Blog::getStatus, 1)
                .orderByDesc(Blog::getId)
                .last("limit 1");

        Blog blog = iBlogService.getOne(blogQueryWrapper);
        ResultBean<Blog> resultBean = new ResultBean<>();
        if (ObjectUtil.isNotNull(blog)) {
            resultBean.setData(blog);
        } else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }


    @GetMapping("/selectLikeBlogListByPage")
    @SystemLog(description = ConstantUtil.BLOG_FINDKEY,userType=ConstantUtil.USERTYPE_USER)
    @AccessLimit(seconds=1,maxCount=15)
    public ResultBean<IPage<Blog>> selectLikeBlogListByPage(Blog blog,
                                                            String param,
                                                            @RequestParam(value = "sort", required = true, defaultValue = "addTime")
                                                                    String sort,
                                                            @RequestParam(value = "page", required = true, defaultValue = "1")
                                                                    Integer page,
                                                            @RequestParam(value = "pageSize", required = true, defaultValue = "10")
                                                                    Integer pageSize
    ) {
        QueryWrapper<Blog> blogQueryWrapper = listMap(blog, sort);
        //分页数据
        Page<Blog> blogPage = new Page<>();
        blogPage.setCurrent(page);
        blogPage.setSize(pageSize);
        Page<Blog> blogPage1 = iBlogService.page(blogPage, blogQueryWrapper);
        ResultBean<IPage<Blog>> resultBean = new ResultBean<>();
        if (ObjectUtil.isNotNull(blogPage1.getRecords())) {
            resultBean.setData(blogPage1);
        } else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }


    /**
     * 分组查询博客信息，不包括博客内容
     *
     * @param blog     博客实体类属性
     * @param sort     排序规则
     * @param page     当前页
     * @param pageSize 一页几条内容
     * @return 返回数据包括分页数据
     */
    @AccessLimit(seconds = 1, maxCount = 15)
    @GetMapping("/selectGroupLikeBlogListByPage")
    public ResultBean<IPage<Blog>> selectGroupLikeBlogListByPage(
            Blog blog,
            @RequestParam(value = "sort", defaultValue = "addTime") String sort,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize
    ) {
        QueryWrapper<Blog> blogQueryWrapper = listMap(blog, sort);
        //排除博客内容content
        blogQueryWrapper.select(Blog.class, i -> !"content".equals(i.getColumn()));
        //分页显示
        IPage<Blog> iPage = new Page<>();
        iPage.setCurrent(page);
        iPage.setSize(pageSize);
        IPage<Blog> iPage1 = iBlogService.page(iPage, blogQueryWrapper);
        ResultBean<IPage<Blog>> resultBean = new ResultBean<>();
        if (ObjectUtil.isNotNull(iPage1.getRecords())) {
            resultBean.setData(iBlogService.page(iPage, blogQueryWrapper));
        } else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    /**
     * 初始化每个类别，并往每个类别里传入属性
     *
     * @return 数据，代码看不懂，没关系，我也看不懂
     */
    @GetMapping("/selectBlogByAllType")
    public ResultBean<Map<String,Object>> selectBlogByAllType() {

        QueryWrapper<BlogType> blogTypeQueryWrapper = new QueryWrapper<>();

        //这里不想写注释，我又怕我自己忘了，我丢，写！！
        //这里只需要获取5个类别。
        //对不起写错了，这里需要获取6个，我已经改过来了，不用担心
        blogTypeQueryWrapper.lambda().orderByAsc(BlogType::getAddTime).last("limit 6");
        HashMap<String, Object> map = new HashMap<>();

        ResultBean<Map<String, Object>> resultBean = new ResultBean<>();
        List<BlogType> list = iBlogTypeService.list(blogTypeQueryWrapper);

        if (list.size() == 0){
            resultBean.setCode(ResultBean.FAIL);
            return resultBean;
        }
        for (BlogType blogType : list) {
            QueryWrapper<Blog> blogQueryWrapper = new QueryWrapper<>();
            blogQueryWrapper.lambda().eq(Blog::getTypeId, blogType.getId()).eq(Blog::getStatus, 1).orderByDesc(Blog::getClickNum);
            //这里也不需要查询内容，
            blogQueryWrapper.select(Blog.class, i -> !"content".equals(i.getColumn()));
            Page<Blog> page = iBlogService.page(new Page<>(1, 6), blogQueryWrapper);
            map.put(blogType.getTypeName(), page);
        }

        resultBean.setData(map);

        return resultBean;
    }

    /**
     * 工具方法
     *
     * @param blog 传入的博客属性
     * @param sort 排序方式
     * @return 返回条件构造器
     */
    public static QueryWrapper<Blog> listMap(Blog blog, String sort) {

        QueryWrapper<Blog> blogQueryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(blog.getTitle())) {
            blogQueryWrapper.lambda().like(Blog::getTitle, blog.getTitle()).or();
        }

        if (StrUtil.isNotBlank(blog.getIntroduction())) {
            blogQueryWrapper.lambda().like(Blog::getIntroduction, blog.getIntroduction()).or();
        }

        if (StrUtil.isNotBlank(blog.getKeyword())) {
            blogQueryWrapper.lambda().like(Blog::getKeyword, blog.getKeyword());
        }

        if (blog.getIsTop() != null) {
            blogQueryWrapper.lambda().eq(Blog::getIsTop, blog.getIsTop());
        }

        if (blog.getTypeId() != null) {
            blogQueryWrapper.lambda().eq(Blog::getTypeId, blog.getTypeId());
        }
        if (blog.getStatus() != null) {
            blogQueryWrapper.lambda().eq(Blog::getStatus, blog.getStatus());
        }

        if (blog.getIsRecommend() != null) {
            blogQueryWrapper.lambda().eq(Blog::getIsRecommend, blog.getIsRecommend());
        }
        if (blog.getAddTime() != null) {
            blogQueryWrapper.lambda().eq(Blog::getAddTime, blog.getAddTime());
        }

        switch (sort) {
            case "addTime":
                blogQueryWrapper.lambda().orderByDesc(Blog::getAddTime);
                break;
            case "clickNum":
                blogQueryWrapper.lambda().orderByDesc(Blog::getClickNum);
            default:
                break;
        }
        return blogQueryWrapper;
    }
}
